package com.unknowpupil.design.sigleton;

/**
 * @Description: <br/>
 * <p>
 * 单例 双重检测锁式
 * 问题： 由于编译器优化原因和JVM底层内部模型原因，偶尔会出现问题
 * 实际工作用不上
 * 优点：将同步内容小法到if内部，提高执行小路 不必每次获取对象都进行同步，只有第一次同步创建了以后就没必要了。
 * </p>
 * @Author: <a> w10g </a>
 * @CreateDate: Create in 2020/4/24 16:41
 * @Classname: DoubleCheckLockSingleton
 * @Version: 1.0
 */
public class DoubleCheckLockSingleton {
    /**
     * 2 提供静态属性
     * 初始化时候，不立即加载 用的时候在实例化
     *
     * 但是在java 8 后 加入 volatile 即可解决问题。
     * volatile（java5）：可以保证多线程下的可见性;
     *
     * 读volatile：每当子线程某一语句要用到volatile变量时，都会从主线程重新拷贝一份，这样就保证子线程的会跟主线程的一致。
     *
     * 写volatile: 每当子线程某一语句要写volatile变量时，都会在读完后同步到主线程去，这样就保证主线程的变量及时更新。
     */
    private static volatile DoubleCheckLockSingleton instance = null;

    /**
     * 1 私有构造，不让别人访问
     */
    private DoubleCheckLockSingleton() {
    }

    /**
     * 双重锁机制，  以前最完美的。
     * @return
     */
    public static  DoubleCheckLockSingleton getInstance() {
        if (instance == null) {
            DoubleCheckLockSingleton ins;
            // if 级别同步，比 方法级别快多了。
            synchronized (DoubleCheckLockSingleton.class) {
                ins = instance;
                if (ins == null) {
                    synchronized (DoubleCheckLockSingleton.class) {
                        if (ins == null) {
                            ins = new DoubleCheckLockSingleton();
                        }
                    }
                    instance = ins;
                }
            }
        }
        return instance;
    }

    private Object readResolve() {
        return instance;
    }
}
